<!-- 双缓冲技术解决canvas重绘闪动问题 -->
<template>
  <div ref="container" class="container">
      <!-- <div class="mask">
          <span style="mix-blend-mode: multiply;">KOOND66</span>
      </div> -->
      <canvas id="myCanvas" :width="width" :height="height"></canvas>
      <canvas id="myCanvas1" :width="width" :height="height" style="opacity: 0;"></canvas>
  </div>
</template>

<script>
  export default {
      data() {
          return {
              animationFrameId: null,
              isAdmation: false,
              flag: true,
              width: null,
              height: null,
              list: [],
              timer: null
          }
      },
      async mounted() {
          this.width = this.$refs.container.clientWidth
          this.height = this.$refs.container.clientHeight
          await this.computedCircle()
          window.addEventListener('resize', this.handleResize);
      },
      beforeDestroy() {
          window.cancelAnimationFrame(this.animationFrameId);
      },
      methods: {
          startAdmation() {
              this.requestAdmationStart()
          },
          requestAdmationStart() {
              this.move()
              window.cancelAnimationFrame(this.animationFrameId);
              this.animationFrameId = window.requestAnimationFrame(this.requestAdmationStart)
          },
          handleResize() {
              this.width = this.$refs.container.clientWidth
              this.height = this.$refs.container.clientHeight
              // this.initBall(true)
              let canvas = document.getElementById('myCanvas')
              let content = canvas.getContext('2d')
              let tempCanvas = document.getElementById('myCanvas1');
              let tempCtx = tempCanvas.getContext('2d');
              tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height)
              this.list.forEach(item => {
                  tempCtx.beginPath()
                  tempCtx.arc(item.x, item.y, item.r, 0, Math.PI * 2, false)
                  tempCtx.fillStyle = item.color
                  tempCtx.fill()
              })
              const imageData = tempCtx.getImageData(0, 0, tempCtx.canvas.width, tempCtx.canvas.height);
              //content.clearRect(0, 0, content.canvas.width, content.canvas.height)
              content.putImageData(imageData, 0, 0); // 渲染到显示的canvas上
              // this.startAdmation()
          },
          computedCircle() {
              let canvas = document.getElementById('myCanvas')
              let content = canvas.getContext('2d')
              for(let i = 0; i < 10; i++) {
                  let newR = 50 * Math.random()+10
                  this.list[i] = {
                      r: newR,
                      x: content.canvas.width * Math.random() <= newR + 200 ? content.canvas.width * Math.random() + newR + 200: content.canvas.width * Math.random() > content.canvas.width - newR ? content.canvas.width - newR : content.canvas.width * Math.random(),
                      y: content.canvas.height * Math.random() <= newR + 200 ? content.canvas.height * Math.random() + newR + 200: content.canvas.height * Math.random() > content.canvas.height - newR ? content.canvas.height - newR : content.canvas.height * Math.random(),
                      vx: 4 * Math.random()-2,
                      vy: 4 * Math.random()-2,
                      color: 'rgba(' +
                          (Math.random() * 255).toFixed(0) + ',' +
                          (Math.random() * 255).toFixed(0) + ',' +
                          (Math.random() * 255).toFixed(0) + ',' +
                          (0.5+0.5*Math.random()).toFixed(1) + ')'
                  }
              }
              this.initBall(true)
          },
          initBall(flag) {
              let canvas = document.getElementById('myCanvas')
              let content = canvas.getContext('2d')
              content.clearRect(0, 0, content.canvas.width, content.canvas.height)
              this.list.forEach(item => {
                  content.beginPath()
                  content.arc(item.x, item.y, item.r, 0, Math.PI * 2, false)
                  content.fillStyle = item.color
                  content.fill()
              })
              if(flag) {
                  this.startAdmation()
              }
          },
          move() {
              let canvas = document.getElementById('myCanvas')
              let content = canvas.getContext('2d')
              this.list.forEach(item => {
                  if(item.x + item.vx > content.canvas.width - item.r || item.x + item.vx < 0 + item.r) {
                      item.vx = -item.vx
                  }
                  if(item.y + item.vy > content.canvas.height - item.r || item.y + item.vy < 0 + item.r) {
                      item.vy = -item.vy
                  }
                  item.x += item.vx
                  item.y += item.vy
              })
              let tempCanvas = document.getElementById('myCanvas1');
              let tempCtx = tempCanvas.getContext('2d');
              tempCtx.clearRect(0, 0, tempCtx.canvas.width, tempCtx.canvas.height)
              this.list.forEach(item => {
                  tempCtx.beginPath()
                  tempCtx.arc(item.x, item.y, item.r, 0, Math.PI * 2, false)
                  tempCtx.fillStyle = item.color
                  tempCtx.fill()
              })
              const imageData = tempCtx.getImageData(0, 0, tempCtx.canvas.width, tempCtx.canvas.height); // 先缓存最新的数据
              content.clearRect(0, 0, content.canvas.width, content.canvas.height)
              content.putImageData(imageData, 0, 0); 
          }
      }
  }
</script>

<style lang="less" scoped>
  .container {
      width: 80%;
      height: 80%;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
  }
  canvas {
      width: 100%;
      height: 100%;
      border: 1px solid #eee;
  }
  .mask {
      width: 100%;
      height: 100%;
      position: absolute;
      background-color: black;
      left: 0;
      top: 0;
      font-size: 100px;
      font-weight: 700;
      // color: aliceblue;
      display: flex;
      justify-content: center;
      align-items: center;
  }
  #myCanvas1 {
      position: absolute;
      left: -9999999999999999px;
      top: -99999999999999px;
  }
</style>